﻿using DevExpress.Utils.Menu;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using FlyHorse.LIMS.WinApp.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FlyHorse.LIMS.WinApp.Utils
{
    public static class SummaryCalculate
    {
        /// <summary>
        /// 创建一个用来计算的List
        /// </summary>
        /// <param name="gridView1"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        public static List<double> GreateDataList(GridView gridView1, GridColumn column)
        {
            List<double> dataList = new List<double>();
            for (int i = 0; i < gridView1.RowCount; i++)
            {
                object value = gridView1.GetRowCellValue(i, column);
                if (value != null)
                {
                    dataList.Add(Convert.ToDouble(value));
                }
            }
            return dataList;
        }



        /// <summary>
        /// 计算数量条数
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static int GetCountValue(List<double> dataList)
        {
            return dataList.Count;
        }


        /// <summary>
        /// 计算最大值
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetMaxValue(List<double> dataList)
        {
            double? value = null;
            dataList = dataList.OrderByDescending(m => m).ToList();
            if (dataList.Count > 0)
            {
                value = dataList[0];
            }
            return value;
        }

        /// <summary>
        /// 计算最小值
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetMinValue(List<double> dataList)
        {
            double? value = null;
            dataList = dataList.OrderBy(m => m).ToList();
            if (dataList.Count > 0)
            {
                value = dataList[0];
            }
            return value;
        }

        /// <summary>
        /// 计算中值
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetMidValue(List<double> dataList)
        {
            double? value = null;
            dataList = dataList.OrderBy(m => m).ToList();
            int count = dataList.Count;
            if (count > 2)
            {
                //奇数

                bool isJishu = (count % 2 == 1) ? true : false;
                if (isJishu)
                {
                    value = dataList[(count / 2)];
                }
                else
                {
                    double val1 = dataList[(count / 2) - 1];
                    double val2 = dataList[(count / 2)];
                    value = (val1 + val2) / 2;
                }
            }
            else if (count == 2)
            {
                double val1 = dataList[0];
                double val2 = dataList[1];
                value = (val1 + val2) / 2;
            }
            else if (count == 1)
            {
                value = dataList[0];
            }
            else if (count == 0)
            {
                value = null;
            }

            return value;
        }


        /// <summary>
        /// 计算总和
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetSumValue(List<double> dataList)
        {
            double? value = null;
            if (dataList.Count > 0)
            {
                double total = 0;
                foreach (var data in dataList)
                {
                    total += data;
                }
                value = total;
            }
            return value;
        }


        /// <summary>
        /// 计算平均值
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetAvgValue(List<double> dataList)
        {
            double? value = null;
            if (dataList.Count > 0)
            {
                double total = 0;
                foreach (var data in dataList)
                {
                    total += data;
                }
                value = total / dataList.Count;
            }
            return value;

        }


        /// <summary>
        /// 计算全距Range
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetRangeValue(List<double> dataList)
        {
            double? value = null;
            dataList = dataList.OrderBy(m => m).ToList();
            if (dataList.Count > 1)
            {
                value = dataList[dataList.Count - 1] - dataList[0];
            }
            return value;

        }


        /// <summary>
        /// 计算sigma
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetSigmaValue(List<double> dataList)
        {
            double? value = null;
            if (dataList.Count == 0)
            {
                return value;
            }
            //计算平均值
            double? average = GetAvgValue(dataList);
            if (average != null)
            {
                double avg = Convert.ToDouble(average);
                double valSum = 0;
                foreach (var data in dataList)
                {
                    double val = Math.Pow(data - avg, 2);
                    valSum += val;
                }
                value = Math.Sqrt(valSum / dataList.Count);
            }
            return value;
        }


        /// <summary>
        /// 计算样本标准偏差 S
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetSValue(List<double> dataList)
        {
            double? value = null;
            if (dataList.Count == 0)
            {
                return value;
            }
            //计算平均值
            double? average = GetAvgValue(dataList);
            if (average != null)
            {
                double avg = Convert.ToDouble(average);
                double valSum = 0;
                foreach (var data in dataList)
                {
                    double val = Math.Pow(data - avg, 2);
                    valSum += val;
                }
                value = Math.Sqrt(valSum / (dataList.Count - 1));
            }
            return value;
        }


        /// <summary>
        /// 计算精密度CP（规格公差除以6Sigma）
        /// </summary>
        /// <param name="dataList">需要计算的数据</param>
        /// <param name="usl">规格上线</param>
        /// <param name="lsl">规格下线</param>
        /// <returns></returns>
        public static double? GetCPValue(List<double> dataList, double lsl, double usl)
        {
            double? value = null;
            double T = usl - lsl;
            double? s = GetSValue(dataList);
            if (s != null)
            {
                value = T / (6 * s);
            }
            return value;
        }


        /// <summary>
        /// 计算CP  （只有上限）
        /// </summary>
        /// <param name="dataList"></param>
        /// <param name="usl"></param>
        /// <returns></returns>
        public static double? GetCPValue(List<double> dataList, double sl,bool isUp)
        {
            double? value = null;
            if (isUp)
            {
               
                double? avg = GetAvgValue(dataList);
                double? s = GetSValue(dataList);
                if (s != null && avg != null)
                {
                    value = (sl - avg) / (3 * s);
                }
                return value;
            }
            else
            {
                double? avg = GetAvgValue(dataList);
                double? s = GetSValue(dataList);
                if (s != null && avg != null)
                {
                    value = (avg - sl) / (3 * s);
                }

                return value;
            }
            
        }


        /// <summary>
        /// 计算CP（只有下限）
        /// </summary>
        /// <param name="dataList"></param>
        /// <param name="lsl"></param>
        /// <returns></returns>
        //public static double? GetCPValue(List<double> dataList, double lsl)
        //{
        //    double? value = null;
         
        //}


        /// <summary>
        ///  准确度CA ,Ca仅适用于双边规格, 单边规格无法计算Ca
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetCAValue(List<double> dataList, double lsl, double usl)
        {
            double? value = null;
            if (GetAvgValue(dataList) == null)
            {
                return null;
            }
            double avg = (double)GetAvgValue(dataList);
            double U = (usl + lsl) / 2;
            double T = (usl - lsl) / 2;
            value = Math.Abs((avg - U) / (T / 2));
            return value;
        }

        /// <summary>
        ///  制程能力指数 CPK 仅适用于双边规格，单边规格CPK =CA
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public static double? GetCPKValue(List<double> dataList, double lsl, double usl)
        {
            double? value = null;
            if (GetSigmaValue(dataList) != null && GetAvgValue(dataList)!=null)
            {
                double sigma = (double)GetSigmaValue(dataList);
                double avg = (double)GetAvgValue(dataList);
                double val1 = (usl - avg) / (3 * sigma);
                double val2 = (avg - lsl) / (3 * sigma);
                if (val1>val2)
                {
                    value = val2;
                }
                else
                {
                    value = val1;
                }
            }  
            return value;
        }

    }
}
